package org.xzheng.repayment.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.xzheng.repayment.entity.ReplayPlan;
import org.xzheng.repayment.service.IRepayPlanGenerator;
import org.xzheng.repayment.util.DateUtil;

/**
 * 等本等息。 误差放在第一个月
 * 
 * <pre>
总收益＝借款金额×借款利率×借款月数n/12
总本金＝借款金额
总本息＝总收益＋总本金
2至n月收益＝月还利息＝总收益/借款月数，保留两位小数，第三位起舍去
2至n月收本金＝月还本金＝向下取整（借款金额/借款月数）
2至n月结算额＝月还款额＝月利息＋月还本金，保留两位小数，不足补0，下同
1月收益＝总收益－求和（2至n月收益）
1月本金＝总本金－求和（2至n月本金）
1月本金及收益＝1月收益＋1月本金
 * </pre>
 */
public class RePayAlgorithmAverageCapital implements IRepayPlanGenerator {

	@Override
	public Map<Integer, ReplayPlan> getRepayPlan(double principal, double yearRate, int totalmonth, Date beginDate) {
		Map<Integer, ReplayPlan> map = new HashMap<Integer, ReplayPlan>();
		DateTime before = null;
		DateTime after = null;

		DateTime beginBase = new DateTime(beginDate);
		beginBase = beginBase.plusDays(-1);

		// 总收益＝借款金额×借款利率×借款月数n/12
		BigDecimal totalInterest = new BigDecimal(principal);
		try {
			totalInterest = totalInterest.multiply(new BigDecimal(yearRate)).multiply(new BigDecimal(totalmonth))
					.divide(new BigDecimal(12), 2, BigDecimal.ROUND_HALF_UP);
		} catch (Exception e) {
			e.printStackTrace();
		}
		totalInterest = totalInterest.setScale(2, BigDecimal.ROUND_HALF_UP);

		// 2至n月收益
		BigDecimal perMonthInterest = totalInterest.divide(new BigDecimal(totalmonth), 2, BigDecimal.ROUND_DOWN);

		// 2至n月收本金
		BigDecimal perMonthPrincipal = new BigDecimal(principal);
		perMonthPrincipal = perMonthPrincipal.divide(new BigDecimal(totalmonth), 2, BigDecimal.ROUND_DOWN);

		// 2至n月收益，总额
		BigDecimal totaInterestWithOutFirst = perMonthInterest.multiply(new BigDecimal(totalmonth - 1));
		// 2至n月收本金，总额
		BigDecimal totaPrincipalWithOutFirst = perMonthPrincipal.multiply(new BigDecimal(totalmonth - 1));

		for (int i = 0; i < totalmonth; i++) {
			int period = i + 1;

			if (after == null) {
				before = new DateTime(beginDate);
			} else {
				before = after.plusDays(1);
			}

			after = new DateTime(DateUtil.add_month(beginBase.toDate(), period));

			int days = Days.daysBetween(before, after).getDays() + 1;

			ReplayPlan plan = new ReplayPlan(period, yearRate, perMonthInterest, perMonthPrincipal, before.toDate(),
					after.toDate(), days);

			map.put(period, plan);
		}

		ReplayPlan firstMonth = map.get(1);

		// 1月收益＝总收益－求和（2至n月收益）
		BigDecimal firstInterest = new BigDecimal(totalInterest.doubleValue() - totaInterestWithOutFirst.doubleValue());
		firstInterest = firstInterest.setScale(2, BigDecimal.ROUND_HALF_UP);
		firstMonth.setInterest(firstInterest);
		// 1月本金＝总本金－求和（2至n月本金）
		BigDecimal firstPrincipal = new BigDecimal(principal - totaPrincipalWithOutFirst.doubleValue());
		firstPrincipal = firstPrincipal.setScale(2, BigDecimal.ROUND_HALF_UP);
		firstMonth.setPrincipal(firstPrincipal);
		// 1月本金及收益＝1月收益＋1月本金
		firstMonth.setTotalAmount(firstInterest.add(firstPrincipal));

		return map;
	}

	public static void main(String[] args) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date begin = sdf.parse("2017-08-30");
		Map<Integer, ReplayPlan> detailPlan = new RePayAlgorithmAverageCapital().getRepayPlan(4000, 0.1238, 24, begin);
		System.out.println("等本等息");
		for (int i = 1; i <= detailPlan.size(); i++) {
			ReplayPlan plan = detailPlan.get(i);
			System.out.println(plan);
		}
	}
}
